#ifndef __PORT_H__
#define __PORT_H__

#include "types.h"
#include "LPC17xx.h"
#include "kern_conf.h"

/* critical region handling */
//naive implementation
//__inline and asm should go to compiler abstraction layer
static __inline __asm void cpsie()
{
	PRESERVE8
	cpsie i	
	bx r14

};

static __inline __asm void cpsid()
{
	PRESERVE8
	cpsid i
	bx r14
};


#define  DISABLE_INTERRUPTS() cpsid()
#define  ENABLE_INTERRUPTS()  cpsie()

#define STACK_GROWTH 1  // 1 if stack grows from High to Low memory

#define SWITCH_CONTEXT() {SCB->ICSR |= 1 << 28;}

/**TODO: 2) Create the alternative implementation for STACK_GROWTH 0
 * @brief: Port specific function. Used to initialize the stack of a newly
 *         created task. Is must look as if it was just interrupted.
 */

OSStackType *StkInit(OSStackType *tos, task function, void *args, OSStackType stack_size);

void swap(void);
void context_switch(void);
void init_service(void);
uint_32 OSTickConfig(void);
void OSTickStart(void);

#if HIGHEST_PRIO_ALT == 3

#if MAX_PRIO > 32
#error "Number of task priorities is too damn high for using port specific FindHighestPriorityTask.\
		Either use less tasks or change HIGHEST_PRIO_ALT in kern_conf.h"
#endif
#define FindHighestPriorityTask()	{highestTCB = TaskArray[31 - __clz(ReadyTaskBitmap)];}
#endif

// system calls declarations here
//compiler abstraction?
void __svc(0x23) start_os(void);

#ifdef __DEBUG__
void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress );
#endif
#endif
